import numpy as np
import plotly.graph_objects as go
from plotly.subplots import make_subplots
from scipy import constants
import sys
!{sys.executable} -m pip install plotly
a0 = constants.physical_constants['Bohr radius'][0]
Angstrom = constants.angstrom
Requirement already satisfied: plotly in c:\users\alex1\anaconda3\lib\site-packages (5.9.0) Requirement already satisfied: tenacity>=6.2.0 in c:\users\alex1\anaconda3\lib\site-packages (from plotly) (8.2.2)
def r_phi_theta(x, y, z):
r = np.sqrt(x**2 + y**2 + z**2)
phi = np.arctan2(y, x) + np.pi
theta = np.arccos(z/r)
return r, phi, theta
X, Y, Z = np.mgrid[-20*a0:20*a0:48j, -20*a0:20*a0:48j, -20*a0:20*a0:48j]
r_grid, phi_grid, theta_grid = r_phi_theta(X, Y, Z)
def probfunc(r, wavefunc):
p = r**2 * np.conj(wavefunc) * wavefunc
return p.real / np.max(p.real)
# The .real syntax picks off the real part of a complex number. Even though the
# imaginary part of the probability is zero, variable p is still represented in
# the computer as a complex number. Our plotting routines will only work on
# arrays of real numbers.
Question 1: How come these wave functions do not depend on $\phi$ and $\theta$?
# n = 3, l = 2, m = 2
n3l2m2 = lambda r, phi, theta: (r**2/a0**2) * np.exp(-r/(3*a0)) * np.sin(theta) * \
np.exp(2j * phi) / \
(162 * np.sqrt(np.pi) * a0**1.5)
prob_n3l2m2 = probfunc(r_grid, n3l2m2(r_grid, phi_grid, theta_grid))
fig = go.Figure(data=go.Isosurface(
x=X.flatten() / Angstrom, # x values of the grid in Angstroms
y=Y.flatten() / Angstrom, # y values of the grid in Angstroms
z=Z.flatten() / Angstrom, # z values of the grid in Angstroms
value=prob_n3l2m2.flatten(), # independent variable
isomin=0.05, # Minimum normalized probability density to render in an isosurface
isomax=0.95, # Maximum normalized probability density to render in an isosurface
opacity=0.4, # Set a low opacity so each surface is partially transparent
colorscale='Plotly3_r', # Nice-looking color table
surface_count=8, # number of isosurfaces to plot (2 by default: only min and max)
colorbar_nticks=8, # colorbar ticks correspond to isosurface values
caps=dict(x_show=False, y_show=False, z_show=False))
)
# Change axis lables and make the plot larger than the default
fig.update_layout(scene = dict(
xaxis_title='x (Angstroms)',
yaxis_title='y (Angstroms)',
zaxis_title='z (Angstroms)'),
width=700,
margin=dict(r=10, b=10, l=10, t=10))
fig.show()